package com.gopay.commons.validator;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.dom4j.Document;
import org.dom4j.Element;

import com.gopay.commons.validator.form.Field;
import com.gopay.commons.validator.form.Form;
import com.gopay.commons.validator.form.Validator;

/**
 * 构建验证对象(容器启动时调用)
 * 
 * @FormBuilder.java
 * @author yaobo
 * @2012-12-26 上午09:54:18 www.gopay.com.cn Inc.All rights reserved.
 */
public class FormBuilder {
    private static final String SELECT_FORMS = "/forms/form";

    public void builder(Document document) {
        DefaultFormService.forms = builderForm(document);
    }

    /**
     * 拼装FORM对象
     * 
     * @return
     */
    @SuppressWarnings("unchecked")
    private Map<String, Form> builderForm(Document document) {
        if (document == null) {
            return null;
        }

        List<Element> forms = document.selectNodes(SELECT_FORMS);
        if (forms == null || forms.size() == 0) {
            return null;
        }

        Element element = null;
        Form form = null;
        Map<String, Form> formMap = new HashMap<String, Form>();
        Map<String, Field> fieldMap = null;
        String name = "";
        String extendsValue = "";
        String postOnly = "";

        for (Iterator<Element> it = forms.iterator(); it.hasNext();) {
            element = (Element) it.next();
            form = new Form();

            name = element.attributeValue("name");
            extendsValue = element.attributeValue("extends");
            postOnly = element.attributeValue("postOnly");

            form.setFormName(name);
            form.setFormExtends(extendsValue);
            if (StringUtils.isNotBlank(postOnly) && StringUtils.equalsIgnoreCase("true", postOnly)) {
                form.setPostOnly(true);
            }

            fieldMap = builderField(element.elements());
            form.setFields(fieldMap);

            formMap.put(form.getFormName(), form);
        }

        return formMap;
    }

    /**
     * 拼装Field对象
     * 
     * @param document
     * @return
     */
    @SuppressWarnings("unchecked")
    private Map<String, Field> builderField(List<Element> fields) {
        if (fields == null || fields.size() == 0) {
            return null;
        }

        Field field = null;
        Element element = null;
        Map<String, Field> fieldMap = new HashMap<String, Field>();

        for (Iterator<Element> it = fields.iterator(); it.hasNext();) {
            element = (Element) it.next();

            field = new Field();
            field.setFieldName(element.attributeValue("name"));
            field.setDisplayName(element.attributeValue("displayName"));
            List<Validator> validators = builderValidator(element.elements());
            field.setValidators(validators);

            fieldMap.put(field.getFieldName(), field);
        }

        return fieldMap;
    }

    /**
     * 拼装Validator对象
     * 
     * @param validators
     * @return
     */
    private List<Validator> builderValidator(List<Element> validators) {
        if (validators == null || validators.size() == 0) {
            return null;
        }

        Element element = null;
        Validator validator = null;
        List<Validator> validatorArray = new ArrayList<Validator>();

        for (Iterator<Element> it = validators.iterator(); it.hasNext();) {
            element = (Element) it.next();

            validator = convertValidator(element);
            validatorArray.add(validator);
        }

        return validatorArray;
    }

    @SuppressWarnings("unchecked")
    private Validator convertValidator(Element element) {
        if (element == null) {
            return null;
        }

        Validator validator = new Validator();
        String requried = element.attributeValue("required");
        String minLength = element.attributeValue("minLength");
        String maxLength = element.attributeValue("maxLength");
        String pattern = element.attributeValue("pattern");
        String minValue = element.attributeValue("minValue");
        String maxValue = element.attributeValue("maxValue");
        String compareTo = element.attributeValue("compareTo");
        String value = element.attributeValue("value");
        String type = element.attributeValue("type");
        String message = null;

        List<Element> messageEle = element.elements();
        if (messageEle != null) {
            for (Iterator<Element> it = messageEle.iterator(); it.hasNext();) {
                Element e = (Element) it.next();
                message = e.getText();
                break;
            }
        }

        if (StringUtils.isNotBlank(requried) && StringUtils.equalsIgnoreCase("true", requried)) {
            validator.setRequried(true);
        }
        if (StringUtils.isNotBlank(minLength)) {
            validator.setMinLength(minLength);
        }
        if (StringUtils.isNotBlank(maxLength)) {
            validator.setMaxLength(maxLength);
        }
        if (StringUtils.isNotBlank(minValue)) {
            validator.setMinValue(minValue);
        }
        if (StringUtils.isNotBlank(maxValue)) {
            validator.setMaxValue(maxValue);
        }
        validator.setPattern(pattern);
        validator.setCompareTo(compareTo);
        validator.setValue(value);
        validator.setType(type);
        validator.setMessage(message);

        return validator;
    }

}